import { parseHTML } from "./parse"



function genProps(attrs) {
  let str = ''
  for (let i = 0; i < attrs.length; i ++ )  {
    let attr = attrs[i]
    // style 特殊处理
    if(attr.name==='style'){
      let styleObj = {}
      attr.value.split(';').forEach(item=>{
      
        const [key,value] = item.split(':')
        styleObj[key] = value
      })
      attr.value = styleObj 
    }

    str += `${attr.name}:${JSON.stringify(attr.value)},`
  }
  return `{${str.slice(0, -1)}}`
}

function gen(node){
  if(node.type === 1){
    return codegen(node)
  } else {
    let text = node.text
    const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g
    if (!defaultTagRE.test(text)){ // 匹配纯字符
      return `_v('${text}')`

    }else{  // 匹配情况 {{name}} age {{name}} age 
      let tokens =[]
      let match
      defaultTagRE.lastIndex = 0
      let lastIndex = 0
      while (match = defaultTagRE.exec(text)){
        let index =match.index //匹配的位置
        if(index>lastIndex){
          tokens.push(JSON.stringify(text.slice(lastIndex, index)))

        }
        tokens.push(`_s(${match[1].trim()})`)
        lastIndex = index + match[0].length
      }
      if(lastIndex < text.length){
        tokens.push(JSON.stringify(text.slice(lastIndex)))
      }
      return `_v(${tokens.join('+')})`
    }

  }
}

function genChildren(children){
    return children.map(child => gen(child))
  
}

function codegen(ast) {
  let children = genChildren(ast.children)
  let code = `_c(
    '${ast.tag}',
     ${ast.attrs && ast.attrs.length > 0 ? genProps(ast.attrs) : null} 
     ${ast.children.length ? `,${children}`:''})`

    return code 
}


// 模板引擎的实现原理 使用with + new Function
export function compileToFunction(template) {
  // 1.template => ast
  let ast = parseHTML(template)


  // 2.生成render方法 （render方法执行后的返回结果就是虚拟DOM）

  let code = codegen(ast)

  code = `with(this){return ${code}}`

  let render = new Function(code)


  return render
}